import _ from 'lodash-es'
import { useAppStore } from '@/store'
/**
 * 行为种类
 * @typedef Actions
 * @property {any} view 查看
 * @property {any} edit 修改
 * @property {any} add 添加
 * @property {any} del 删除
 */

/**
 * @type { Actions }
 */
const ACTIONS = {
  view: '查看',
  edit: '修改',
  add: '添加',
  del: '删除',
}
/**
 * 配置
 * @typedef Config
 * @property {string} name 模块名称
 * @property {object} initForm 初始表单模板
 * @property {Actions} apis 各种操作api
 * @property {Actions} customAction 各种自定义操作名称
 * @property {function} submitFormat 提交前对参数的格式化操作
 * @property {function} customChange 自定义处理变化
 * @property {function} extraChange 除默认处理外，额外的处理变化
 */
/**
 * @param { Config } config
 */
export const useCrud = ({
  name = '',
  initForm = {},
  apis = {},
  customAction,
  submitFormat,
  customChange,
  extraChange,
  onShow,
  onRender,
}) => {
  const baseActionsMap = _.mapValues(ACTIONS, (action) => `${action}${name}`)
  // 操作名称
  const actions = customAction ? Object.assign(baseActionsMap, customAction) : baseActionsMap
  // 表单存储的数据
  const model = ref(_.cloneDeep(initForm))
  // 弹窗表单操作类型'add'|'edit'|'view'
  const type = ref('')
  // 是否view
  const isView = computed(() => type.value === 'view')
  // 关联的MyForm-ref
  const $form = ref(null)
  // 关联的MyTable-ref
  const $table = ref(null)
  //表单是否数据渲染完成
  const isRender = ref(false)
  // app状态
  const appStore = useAppStore()
  // 设置表单值
  async function setModel(rawData, config = {}) {
    isRender.value = false
    const keys = Object.keys(model.value)
    const data = _.cloneDeep(rawData)
    if (typeof apis.view === 'function' && type.value !== 'add') {
      $form.value.setState('loadingFlag', true)
      const res = await apis.view(data)
      model.value = Object.assign(model.value, _.pick(res, keys))
      $form.value.setState('loadingFlag', false)
    } else {
      model.value = Object.assign(model.value, _.pick(data, keys))
    }
    isRender.value = true
    // 全局渲染表单后回调
    if (typeof onRender === 'function') {
      onRender(type.value, model.value)
    }
    // 单次渲染表单后回调
    if (typeof config?.onRender === 'function') {
      config.onRender(type.value, data)
    }
  }

  /**
   *   显示弹窗
   *   @param {'add'|'edit'|'view'} actionType
   *   @param { object } data
   *   @param { object } config
   */
  function handleShow(actionType, data = {}, config = {}) {
    // 设置类型
    type.value = actionType
    // 设置标题
    $form.value.setState('title', config?.title || `${actions[type.value]}`)
    // 展示modal
    $form.value.setState('showFlag', true)
    // 重置为初始值
    model.value = _.cloneDeep(initForm)
    // 全局展示后回调
    if (typeof onShow === 'function') {
      onShow(type.value, data)
    }
    // 单次配置展示后回调
    if (typeof config?.onShow === 'function') {
      config.onShow(type.value, data)
    }
    // edit与view行为时，去初始化设置表单数据
    if (type.value !== 'add') {
      setModel(data, config)
    }
  }

  /*新增显示弹窗*/
  function handleAdd(config) {
    handleShow('add', _, config)
  }

  /*修改显示弹窗*/
  function handleEdit(data, config) {
    handleShow('edit', data, config)
  }

  /*展示显示弹窗*/
  function handleView(data, config) {
    handleShow('view', data, config)
  }

  /*删除对话框*/
  function handleDel(data, options) {
    type.value = 'del'
    const dialog = $dialog.warning({
      title: '提示',
      content: `确定${actions.del}？`,
      negativeText: '取消',
      positiveText: '确定',
      positiveButtonProps: {
        color: appStore.naiveThemeOverrides.common.primaryColor,
      },
      async onPositiveClick() {
        try {
          dialog.loading = true
          const res = await apis.del(data)
          dialog.loading = false
          handleChange('del', res)
        } catch (error) {
          console.log('error:', error)
          dialog.loading = false
        }
      },
      ...options,
    })
  }

  /*提交新增或者修改*/
  async function handleSubmit() {
    if (!['add', 'edit'].includes(type.value)) return
    let params = model.value
    // 需要格式化
    if (typeof submitFormat === 'function') {
      params = await submitFormat(_.cloneDeep(model.value))
    }
    $form.value.setState('submitFlag', true)
    apis[type.value](params)
      .then((res) => {
        $form.value.setState('submitFlag', false)
        $form.value.setState('showFlag', false)
        handleChange(type.value, res)
      })
      .catch((err) => {
        console.log('err:', err)
        $form.value.setState('submitFlag', false)
      })
  }

  // 默认变动处理
  function defaultHandleChange() {
    // 默认提示语
    $message.success(`${actions[type.value]}成功!`)
    if (type.value === 'add') {
      // 新增时重新加载列表
      $table?.value?.handleSearch()
    } else {
      // 修改/删除时只加载当前页
      $table?.value?.handleQuery()
    }
  }
  /**
   * 进行变动时的处理，如新增/修改/删除数据
   */
  function handleChange(result) {
    if (typeof customChange === 'function') {
      // 自定义处理
      customChange(result, defaultHandleChange)
    } else {
      // 默认处理
      defaultHandleChange()
    }

    if (typeof extraChange === 'function') {
      // 额外处理
      extraChange(result)
    }
  }

  return {
    model,
    type,
    isView,
    isRender,
    $form,
    $table,
    handleAdd,
    handleEdit,
    handleDel,
    handleView,
    handleSubmit,
  }
}
